<template>
  <ElDialog
    v-model="dialogVisible"
    :title="title"
    :width="width"
    :destroy-on-close="destroyOnClose"
    :draggable="draggable"
    :append-to-body="appendToBody"
    :fullscreen="isFullScreen"
    :close-on-click-modal="closeOnClickModal"
    :open-delay="openDelay"
    :close-delay="closeDelay"
    :show-close="false"
    @close="handleClose"
    @open="handleOpen"
  >
    <template #header>
      <slot name="header">
        <div style="position: relative; height: 10px">
          <slot name="title">{{ title }}</slot>
          <div style="position: absolute; top: 0; right: 0; cursor: pointer">
            <span v-if="showFullScreen" class="header-btn">
              <Icon
                :icon="isFullScreen ? 'fullscreen-exit' : 'fullscreen'"
                size="20px"
                @click="isFullScreen = !isFullScreen"
              ></Icon>
            </span>
            <span class="header-btn">
              <ElIcon @click="close" size="20px"><Close /></ElIcon>
            </span>
          </div>
        </div>
      </slot>
    </template>
    <ElScrollbar :style="dialogStyle">
      <slot></slot>
    </ElScrollbar>
    <template #footer>
      <slot name="footer">
        <slot name="beforeFooter" />
        <ElButton @click="handleCancel"> {{ cancelText }} </ElButton>
        <ElButton type="primary" @click="handleSubmit" v-loading="loading"> {{ submitText }} </ElButton>
        <slot name="afterFooter" />
      </slot>
    </template>
  </ElDialog>
</template>

<script setup lang="ts" name="Dialog">
import { computed, nextTick, ref, unref, watch } from "vue";
import { ElDialog, ElIcon, ElScrollbar, ElButton } from "element-plus";
import { Close } from "@element-plus/icons-vue";
import { Icon } from "@/components/Icon";
import { isNumber } from "@/utils/is";
const props = defineProps({
  showFullScreen: {
    type: Boolean,
    default: false
  },
  title: {
    type: String
  },
  fullscreen: {
    type: Boolean,
    default: false
  },
  width: {
    type: String,
    default: "750px"
  },
  appendToBody: {
    type: Boolean,
    default: true
  },
  draggable: {
    type: Boolean,
    default: true
  },
  destroyOnClose: {
    type: Boolean,
    default: false
  },
  closeOnClickModal: {
    type: Boolean,
    default: false
  },
  openDelay: {
    type: Number
  },
  closeDelay: {
    type: Number
  },
  cancelText: {
    type: String,
    default: "取消"
  },
  submitText: {
    type: String,
    default: "确认"
  },
  height: {
    type: String,
    default: "400px"
  }
});
const emit = defineEmits(["close", "submit", "open"]);
const dialogVisible = ref(false);
const isFullScreen = ref(props.fullscreen);
const dialogHeight = ref(isNumber(props.height) ? `${props.height}px` : props.height);
const loading = ref(false);
const flagRef = ref();
const openFlag = ref(false);
const open = (flag?: any) => {
  flagRef.value = flag;
  dialogVisible.value = true;
};
const close = () => {
  dialogVisible.value = false;
};
const handleClose = () => {
  close();
};
const handleOpen = async () => {
  if (!openFlag.value) {
    emit("open");
    openFlag.value = true;
  }
};
const handleCancel = () => {
  close();
};
const openLoading = async (callback: () => void) => {
  loading.value = true;
  try {
    await callback();
  } finally {
    loading.value = false;
  }
};
const handleSubmit = () => {
  emit("submit", flagRef.value);
};
const dialogStyle = computed(() => {
  return {
    height: unref(dialogHeight)
  };
});
watch(
  () => isFullScreen.value,
  async (val: boolean) => {
    await nextTick();
    if (val) {
      const windowHeight = document.documentElement.offsetHeight;
      dialogHeight.value = `${windowHeight - 165}px`;
    } else {
      dialogHeight.value = isNumber(props.height) ? `${props.height}px` : props.height;
    }
  },
  {
    immediate: true
  }
);
defineExpose({ open, close, openLoading });
</script>
<style scoped>
.header-btn {
  margin-left: 10px;
}
</style>
